package ar.edu.uba.fi.jmit.graphvisualizer.client.widget;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import ar.edu.uba.fi.jmit.graphvisualizer.client.Application;
import ar.edu.uba.fi.jmit.graphvisualizer.client.DynamicMenuService;
import ar.edu.uba.fi.jmit.graphvisualizer.client.DynamicMenuServiceAsync;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DecoratedStackPanel;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;

public class DynamicMenuStackPanel extends DecoratedStackPanel {
	
	private Map<String, Tree> applicationMonitors;
	private Map<String, List<String>> applicationMonitorsSerializable;
	private DynamicMenuServiceAsync service = GWT.create(DynamicMenuService.class);
	private Application application;
	
	public DynamicMenuStackPanel(Application application) {
		this.applicationMonitors = new HashMap<String, Tree>();
		this.applicationMonitorsSerializable = new HashMap<String, List<String>>();
		this.application = application;
	}
	
	public void addApplication(String name) {
		this.add(createTreeItem(name), name, false);
	}
	
	public void addMonitor(String appName, String monitorName) {
		applicationMonitors.get(appName).addItem(monitorName).setState(true);
		applicationMonitorsSerializable.get(appName).add(monitorName);
	}
	
	private Tree createTreeItem(String name) {
	    Tree app = new Tree();
	    this.applicationMonitors.put(name, app);
	    app.addSelectionHandler(new SelectionHandler<TreeItem>() {
			
			@Override
			public void onSelection(SelectionEvent<TreeItem> event) {
				GWT.log("DynamicMenuStackPanel.selectionHandler");
				TreeItem item = event.getSelectedItem();
				for (String name : applicationMonitors.keySet()) {
					TreeItem itemSelected = applicationMonitors.get(name).getSelectedItem(); 
					if (itemSelected != null)
						itemSelected.setSelected(false);
				}
				item.setSelected(true);
				application.changeCurrentChart((String)applicationMonitors.keySet().toArray()[getSelectedIndex()],item.getText());
			}
		});
	    
	    List<String> monitors = new LinkedList<String>();
	    this.applicationMonitorsSerializable.put(name, monitors);
	    
	    return app;
	}
	
	public void update() {
		GWT.log("DynamicMenuStackPanel.update");
		service.hasUpdate(applicationMonitorsSerializable, new AsyncCallback<Boolean>() {
			@Override
			public void onSuccess(Boolean hasUpdate) {
				GWT.log("DynamicMenuStackPanel.hasUpdate: OnSuccess");
				if (hasUpdate)
					service.tree(new AsyncCallback<Map<String,List<String>>>() {
						@Override
						public void onSuccess(Map<String, List<String>> appMons) {
							GWT.log("DynamicMenuStackPanel.tree: OnSuccess");
							clear();
							applicationMonitors.clear();
							applicationMonitorsSerializable.clear();
							for (String appKey : appMons.keySet()) {
								addApplication(appKey);
								for (String monKey : appMons.get(appKey))
									addMonitor(appKey, monKey);
							}
						}
						
						@Override
						public void onFailure(Throwable arg0) {
							GWT.log("DynamicMenuStackPanel.tree: Failure");
						}
					});
			}
			
			@Override
			public void onFailure(Throwable e) {
				GWT.log("DynamicMenuStackPanel.hasUpdate: Failure", e);
			}
		});
	}

}
